"""
管理后台的Pydantic模型（用于请求验证和响应序列化）
"""
from pydantic import BaseModel, Field, validator
from typing import Optional, List
from datetime import datetime


# ==================== 通用响应模型 ====================
class ResponseModel(BaseModel):
    """统一响应模型"""
    code: int = Field(default=200, description="状态码")
    message: str = Field(default="success", description="提示信息")
    data: Optional[dict | list] = Field(default=None, description="响应数据")


class PageResponse(BaseModel):
    """分页响应模型"""
    total: int = Field(description="总记录数")
    page: int = Field(description="当前页码")
    page_size: int = Field(description="每页条数")
    items: List[dict] = Field(description="数据列表")


# ==================== 认证相关 ====================
class LoginRequest(BaseModel):
    """登录请求"""
    username: str = Field(..., min_length=3, max_length=64, description="用户名")
    password: str = Field(..., min_length=6, description="密码")


class LoginResponse(BaseModel):
    """登录响应"""
    access_token: str = Field(description="访问令牌")
    refresh_token: str = Field(description="刷新令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    user_info: dict = Field(description="用户信息")


class RefreshTokenRequest(BaseModel):
    """刷新令牌请求"""
    refresh_token: str = Field(..., description="刷新令牌")


# ==================== 管理员用户相关 ====================
class AdminUserCreate(BaseModel):
    """创建管理员"""
    username: str = Field(..., min_length=3, max_length=64, description="用户名")
    password: str = Field(..., min_length=6, description="密码")
    real_name: Optional[str] = Field(None, max_length=50, description="真实姓名")
    email: Optional[str] = Field(None, description="邮箱")
    phone: Optional[str] = Field(None, description="手机号")
    role_id: int = Field(..., description="角色ID")
    status: int = Field(default=1, description="状态：0禁用 1启用")


class AdminUserUpdate(BaseModel):
    """更新管理员"""
    real_name: Optional[str] = Field(None, max_length=50, description="真实姓名")
    email: Optional[str] = Field(None, description="邮箱")
    phone: Optional[str] = Field(None, description="手机号")
    avatar: Optional[str] = Field(None, description="头像URL")
    role_id: Optional[int] = Field(None, description="角色ID")
    status: Optional[int] = Field(None, description="状态：0禁用 1启用")


class AdminUserResponse(BaseModel):
    """管理员响应"""
    id: int
    username: str
    real_name: Optional[str]
    email: Optional[str]
    phone: Optional[str]
    avatar: Optional[str]
    status: int
    last_login_time: Optional[datetime]
    last_login_ip: Optional[str]
    role_id: int
    role_name: Optional[str]
    create_time: datetime
    update_time: datetime

    class Config:
        from_attributes = True


class ChangePasswordRequest(BaseModel):
    """修改密码"""
    old_password: str = Field(..., min_length=6, description="旧密码")
    new_password: str = Field(..., min_length=6, description="新密码")


# ==================== 角色相关 ====================
class RoleCreate(BaseModel):
    """创建角色"""
    name: str = Field(..., max_length=255, description="角色名称")
    code: str = Field(..., max_length=100, description="角色代码")
    description: Optional[str] = Field(None, description="角色描述")
    status: int = Field(default=1, description="状态：0禁用 1启用")


class RoleUpdate(BaseModel):
    """更新角色"""
    name: Optional[str] = Field(None, max_length=255, description="角色名称")
    description: Optional[str] = Field(None, description="角色描述")
    status: Optional[int] = Field(None, description="状态：0禁用 1启用")


class RoleResponse(BaseModel):
    """角色响应"""
    id: int
    name: str
    code: str
    description: Optional[str]
    status: int
    create_time: datetime
    update_time: datetime

    class Config:
        from_attributes = True


class AssignResourcesRequest(BaseModel):
    """分配资源"""
    resource_ids: List[int] = Field(..., description="资源ID列表")


# ==================== 资源相关 ====================
class ResourceCreate(BaseModel):
    """创建资源"""
    name: str = Field(..., max_length=255, description="资源名称")
    code: str = Field(..., max_length=100, description="资源代码")
    type: int = Field(default=1, description="类型：1菜单 2按钮 3接口")
    path: Optional[str] = Field(None, max_length=255, description="前端路由路径")
    icon: Optional[str] = Field(None, max_length=100, description="图标")
    sort: int = Field(default=0, description="排序")
    status: int = Field(default=1, description="状态：0禁用 1启用")
    pid: Optional[int] = Field(None, description="父级资源ID")


class ResourceUpdate(BaseModel):
    """更新资源"""
    name: Optional[str] = Field(None, max_length=255, description="资源名称")
    type: Optional[int] = Field(None, description="类型：1菜单 2按钮 3接口")
    path: Optional[str] = Field(None, max_length=255, description="前端路由路径")
    icon: Optional[str] = Field(None, max_length=100, description="图标")
    sort: Optional[int] = Field(None, description="排序")
    status: Optional[int] = Field(None, description="状态：0禁用 1启用")
    pid: Optional[int] = Field(None, description="父级资源ID")


class ResourceResponse(BaseModel):
    """资源响应"""
    id: int
    name: str
    code: str
    type: int
    path: Optional[str]
    icon: Optional[str]
    sort: int
    status: int
    pid: Optional[int]
    create_time: datetime
    update_time: datetime
    children: Optional[List['ResourceResponse']] = None

    class Config:
        from_attributes = True


# 让ResourceResponse支持递归children
ResourceResponse.model_rebuild()


# ==================== 操作日志相关 ====================
class OperationLogResponse(BaseModel):
    """操作日志响应"""
    id: int
    user_id: int
    username: Optional[str]
    action: str
    module: str
    description: Optional[str]
    ip: Optional[str]
    user_agent: Optional[str]
    status: int
    error_msg: Optional[str]
    create_time: datetime

    class Config:
        from_attributes = True


# ==================== 分页查询请求 ====================
class PageRequest(BaseModel):
    """分页查询请求"""
    page: int = Field(default=1, ge=1, description="页码")
    page_size: int = Field(default=10, ge=1, le=100, description="每页条数")
    keyword: Optional[str] = Field(None, description="关键词搜索")

